<script lang="tsx" setup>
import type { DataTableColumn, UploadFileInfo } from 'naive-ui';
import { NButton, NInput, NSelect, useMessage } from 'naive-ui';
import type { ComponentInternalInstance, VNodeChild } from 'vue';
import { getCurrentInstance, ref } from 'vue';
import type { SelectMixedOption } from 'naive-ui/es/select/src/interface';
import { validFileExcelType, validateFileSize } from '@/utils/fileUtil';
import { useAppStore } from '@/store/modules/app';
import { useThemeStore } from '@/store/modules/theme';
import { importData, parseExcel } from '@/service/api/system/user';
import type { DeptVO, UserVO } from '@/service/types/system';
import type { DictDataOption } from '@/typings/global';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const message = useMessage();
const appStore = useAppStore();
const tab = ref<string>('0');
const parseData = ref<Array<UserVO>>([]);
interface Props {
  deptData: DeptVO[];
  sysUserSex: DictDataOption[];
  sysNormalDisable: DictDataOption[];
}
const props = defineProps<Props>();
const handleRemoveParseData = (index: number) => {
  // parseData[i]
  if (index > -1 && index < parseData.value.length) {
    parseData.value.splice(index, 1);
  }
};
const columns = ref<Array<DataTableColumn<UserVO>>>([
  {
    title: '部门编号',
    key: 'deptId',
    width: 230,
    render: (row: UserVO, index: number): VNodeChild => {
      return (
        <n-tree-select
          value={row.deptId}
          options={props.deptData}
          key-field="id"
          label-field="label"
          children-field="children"
          onUpdate={(v: { value: any }) => {
            parseData.value[index].deptId = v.value;
          }}
        />
      );
    }
  },
  {
    title: '用户账号',
    key: 'userName',
    width: 180,
    render: (row: UserVO, index: number) => {
      return (
        <NInput
          value={row.userName}
          onUpdate:value={v => {
            parseData.value[index].userName = v;
          }}
        />
      );
    }
  },
  {
    title: '用户昵称',
    key: 'nickName',
    width: 180,
    render: (row: UserVO, index) => {
      return (
        <NInput
          value={row.nickName}
          onUpdate:value={v => {
            parseData.value[index].nickName = v;
          }}
        />
      );
    }
  },
  {
    title: '用户邮箱',
    key: 'email',
    width: 180,
    render: (row: UserVO, index) => {
      return (
        <NInput
          value={row.email}
          onUpdate:value={v => {
            parseData.value[index].email = v;
          }}
        />
      );
    }
  },
  {
    title: '手机号',
    key: 'phonenumber',
    width: 180,
    render: (row: UserVO, index) => {
      return (
        <NInput
          value={row.phonenumber}
          onUpdate:value={v => {
            parseData.value[index].phonenumber = v;
          }}
        />
      );
    }
  },
  {
    title: '性别',
    key: 'sex',
    render: (row: UserVO, index: number) => {
      return (
        <NSelect
          value={row.sex}
          options={props.sysUserSex as SelectMixedOption[]}
          onUpdate:value={(v: { value: string }) => {
            return (parseData.value[index].sex = v.value);
          }}
        />
      );
    }
  },
  {
    title: '状态',
    key: 'status',
    render: (row: UserVO, index: number) => {
      return (
        <NSelect
          value={row.status}
          options={props.sysNormalDisable as SelectMixedOption[]}
          onUpdate:value={(v: { value: string }) => {
            return (parseData.value[index].status = v.value);
          }}
        />
      );
    }
  },
  {
    title: '操作',
    key: 'operate',
    align: 'center',
    fixed: 'right',
    width: 100,
    render: (row: UserVO, index: number) => {
      console.log(row);
      return (
        <NButton ghost type="error" size="small" onClick={() => handleRemoveParseData(index)}>
          删除
        </NButton>
      );
    }
  }
]);
defineOptions({
  name: 'ImportModal'
});
const themeStore = useThemeStore();

const importVisible = defineModel<boolean>('importVisible', {
  default: false
});
const radioType = ref<string>('1');
const uploadFile = ref<UploadFileInfo | null>(null);
const loading = ref<boolean>(false);
const result = ref<API.ImportResult | undefined>(undefined);
const beforeUpload = ({ file }: { file: UploadFileInfo; fileList: UploadFileInfo[] }) => {
  if (!validFileExcelType(file.name, file.type as string)) {
    message.error('暂不支持该文件类型');
    return false;
  } else if (!validateFileSize(file.file?.size as number, 10 * 1024 * 1024)) {
    message.error('文件不得超出10M');
    return false;
  }
  uploadFile.value = file;
  return true;
};
const parseExcelData = async () => {
  if (!uploadFile.value?.file) {
    return;
  }
  loading.value = true;
  try {
    const formParams = new FormData();
    formParams.append('file', uploadFile.value.file);

    const { data, error } = await parseExcel(formParams);
    if (error) {
      return;
    }

    parseData.value = data?.data;
    tab.value = '1';
  } finally {
    loading.value = false;
  }
};
const closeModal = () => {
  importVisible.value = false;
};
const resetModal = () => {
  parseData.value = [];
  radioType.value = '0';
  tab.value = '0';
  result.value = undefined;
};
const handleCloseNext = () => {
  if (tab.value === '0' || tab.value === 'analysis') {
    closeModal();
    resetModal();
  } else {
    tab.value = '0';
  }
};
const submitImport = async () => {
  loading.value = true;
  try {
    const { error, data } = await importData(parseData.value, radioType.value);
    loading.value = false;
    if (!error) {
      result.value = data?.data;
      tab.value = 'analysis';
      // analysis
    }
  } catch (r) {
  } finally {
    loading.value = false;
  }
};
const nexTab = () => {
  if (tab.value === '1') {
    // 提交表单
    submitImport();
  } else if (tab.value === '0') {
    // 下一步需要去校验解析
    parseExcelData();
  } else {
    handleCloseNext();
  }
};
const downloadTemplate = () => {
  (proxy as any)?.download({
    url: 'system/user/importTemplate',
    fileName: `user_template_${new Date().getTime()}.xlsx`
  });
};
</script>

<template>
  <NModal v-model:show="importVisible" title="用户导入" preset="card" class="w-800px">
    <Transition :name="themeStore.page.animateMode" mode="out-in" appear>
      <div v-if="tab === '0'">
        <NSpace class="mb-10px">
          <NRadioGroup v-model:value="radioType" name="radius">
            <NRadioButton value="0" label="覆盖原数据" />
            <NRadioButton value="1" label="不覆盖原数据" />
          </NRadioGroup>
        </NSpace>
        <NUpload
          directory-dnd
          :on-before-upload="beforeUpload"
          :max="1"
          accept=".csv, application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        >
          <NUploadDragger>
            <div class="mb-12px">
              <NIcon size="48" :depth="3">
                <SvgIcon icon="tabler:download" />
              </NIcon>
            </div>
            <NText class="font-size-16px">点击或者拖动文件到该区域来上传</NText>
            <NP depth="3" class="mt-8px">请不要上传敏感数据</NP>
          </NUploadDragger>
        </NUpload>
        <NP depth="3" class="mt-8px">
          仅允许导入xls、xlsx格式文件。
          <br />
          覆盖会更新原有的数据
        </NP>
        <NButton text type="primary" @click="downloadTemplate">点击下载用户模板</NButton>
      </div>
      <div v-else-if="tab === '1'" class="h-362px">
        <NDataTable
          :columns="columns"
          :data="parseData"
          size="small"
          :scroll-x="1400"
          :pagination="false"
          :flex-height="!appStore.isMobile"
          :row-key="row => row.userId"
          class="sm:h-full sm:w-full"
        />
      </div>
      <div v-else>
        <NResult v-if="result?.failureNum == 0" status="success">
          <template #default>
            <NH2 class="text-center">恭喜您，数据已全部导入成功！</NH2>
          </template>
          <template #footer>
            <NButton @click="handleCloseNext">关闭</NButton>
          </template>
        </NResult>

        <NScrollbar v-else class="h-300px">
          <div id="importResults">
            <NH3>导入回执如下：</NH3>
            <ul>
              <li v-for="(item, index) in result?.analysis" :key="index">{{ item }}</li>
            </ul>
          </div>
        </NScrollbar>
      </div>
    </Transition>
    <template #footer>
      <NSpace v-if="result == undefined || result?.failureNum !== 0" justify="end">
        <NButton @click="handleCloseNext">{{ tab === '0' ? '取消' : '上一步' }}</NButton>
        <NButton type="primary" :loading="loading" @click="nexTab">
          {{ tab === '1' ? '提交' : result && result?.failureNum !== 0 ? '完成' : '下一步' }}
        </NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style lang="scss" scoped></style>
